package com.ican.nc;

import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import com.ican.common.SystemConstants;
import com.ican.domain.product.Category;
import com.ican.domain.rule.CategoryRule;
import com.ican.domain.rule.ParseRule;
import com.ican.service.product.ProductService;
import com.ican.service.rule.RuleConfigService;

@Service("ncAutoService")
public class NcAutoService{
    private Logger logger = LoggerFactory.getLogger(NcAutoService.class);

    private RuleConfigService ruleConfigService;
    private RuleCategoryScan ruleCategoryScan;
    private ProductService productService;
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    public void updateWebsiteScanNum(){
        ruleConfigService.updateWebsiteScanNum();
    }
    
    public void updateCategoryNcNum(){
        productService.updateCategoryNcNum();
    }
    
    public void scanAuto(){
        CategoryRule category = new CategoryRule();
        category.setDataStatus(SystemConstants.ENTITY_DATE_STATUS_YES);
        category.setScanStatus(SystemConstants.RULE_CONFIG_SCAN_STATUS_NO);
        List<Integer> cIds = ruleConfigService.findAllCategoryIdToScan(category);
        if(cIds != null && cIds.size() > 0){
            for(Integer cid : cIds){
                try{
                    scanProduct(cid);
                }catch(Exception e){
                    logger.error(e.getMessage(),e);
                }
            }
        }
    }
    
    public void ncAuto(){
        List<Integer> cids = productService.findAllCategoryIdsToNcAuto();
        if(cids != null && cids.size() > 0){
            for(Integer cid : cids){
                try{
                    categoryNc(cid);
                }catch(Exception e){
                    logger.error(e.getMessage(),e);
                }
            }
        }
    }
    
    private void scanProduct(Integer cid) {
        CategoryRule cr = ruleConfigService.findCategory(cid);
        //是否可用
        if(cr.getDataStatus() == SystemConstants.ENTITY_DATE_STATUS_NO){
            return;
        }
        //是否未扫描
        if(cr.getScanStatus() != null && cr.getScanStatus() != SystemConstants.RULE_CONFIG_SCAN_STATUS_NO){
            return;
        }
        //查询规则
        ParseRule pr = ruleConfigService.findRule(cr.getRuleId());
        if(pr == null){
            return;
        }
        //生成商品类目
        Category pc = new Category();
        pc.setName(cr.getName());
        pc.setCode(cr.getCode());
        pc.setDescription(cr.getDescription());
        pc.setLangId(cr.getLangId());
        pc.setUrl(cr.getUrl());
        pc.setRuleId(cr.getRuleId());
        productService.addCategory(pc);
        //处理规则
        ParseRuleVo vo = new ParseRuleVo();
        vo.setCateCode(pc.getCode());
        ParseUtil.rule2RuleVo(pr, vo);
        vo.setRuleCateId(cr.getId());
        vo.setProCateId(pc.getId());
        vo.setLangId(cr.getLangId());
        //开始扫描
        ruleConfigService.updateCategoryScanStatus(cr.getId(), SystemConstants.RULE_CONFIG_SCAN_STATUS_RUN);
        ruleCategoryScan.scanCategory(vo, cr.getUrl());
    }

    private void categoryNc(Integer cid) {
        Category category = productService.findCategory(cid);
        if(category.getNcStatus() != null && category.getNcStatus() == SystemConstants.NC_STATUS_RUN){//是否正在运行
            return;
        }
        ParseRule rule = ruleConfigService.findRule(category.getRuleId());
        ParseRuleVo ruleVo = new ParseRuleVo();
        ParseUtil.rule2RuleVo(rule, ruleVo);
        productService.updateCategoryNcStatus(category.getId(), SystemConstants.NC_STATUS_RUN);
        List<Integer> productIds = productService.getAllProductIdForNcByCategory(category.getId(), SystemConstants.NC_STATUS_NO);
        boolean bo = true;
        if(productIds != null){
            for(Integer pid : productIds){
                try{
                    threadPoolTaskExecutor.execute(new RuleProductDetailScan(pid, ruleVo));
                }catch(Exception e){
                    bo = false;
                    break;
                }
            }
        }
        if(bo){
            productService.updateCategoryNcStatus(category.getId(), SystemConstants.NC_STATUS_SUCCESS);
        }else{
            productService.updateCategoryNcStatus(category.getId(), SystemConstants.NC_STATUS_FAILED);
        }
    }
    
    @Resource
    public void setProductService(ProductService productService) {
        this.productService = productService;
    }
    @Resource
    public void setRuleConfigService(RuleConfigService ruleConfigService) {
        this.ruleConfigService = ruleConfigService;
    }
    @Resource
    public void setRuleCategoryScan(RuleCategoryScan ruleCategoryScan) {
        this.ruleCategoryScan = ruleCategoryScan;
    }
    @Resource
    public void setThreadPoolTaskExecutor(ThreadPoolTaskExecutor threadPoolTaskExecutor) {
        this.threadPoolTaskExecutor = threadPoolTaskExecutor;
    }
}
